home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 430_01 / m68kdis / pgen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-29  |  7.0 KB  |  390 lines

  1. /*
  2.  *                 Author:  Christopher G. Phillips
  3.  *              Copyright (C) 1994 All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. /*
  19.  * MC68851 PMMU support.
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "dis.h"
  26. #include "addr.h"
  27.  
  28. static char    *pccs[] = {
  29.     "BS", "BC", "LS", "LC", "SS", "SC", "AS", "AC",
  30.     "WS", "WC", "IS", "IC", "GS", "GC", "CS", "CC"
  31. };
  32. #define NPCCS    (sizeof pccs / sizeof pccs[0])
  33.  
  34. char *
  35. pcc(unsigned condition)
  36. {
  37.     return (condition < NPCCS) ? pccs[condition] : NULL;
  38. }
  39.  
  40. static int
  41. getfc(char *s, unsigned value)
  42. {
  43.     if (value == 0)
  44.         strcpy(s, "SFC");
  45.     else if (value == 1)
  46.         strcpy(s, "DFC");
  47.     else if (value & 0x0010) {
  48.         if (!PMMU(chip) && (value & 8))
  49.             return -1;
  50.         sprintf(s, "FC%d", value & 0xf);
  51.     } else if (value & 8)
  52.         sprintf(s, "D%d", value & 0x7);
  53.     else
  54.         return -1;
  55.  
  56.     return 0;
  57. }
  58.  
  59. static void
  60. pload(m68kword inst, unsigned long value)
  61. {
  62.     int    reg = inst & 7;
  63.     int    mode = (inst >> 3) & 7;
  64.     char    sload[7];
  65.  
  66.     if (!ISACEA(mode, reg))
  67.         return;
  68.     if (value & 0x01de0)
  69.         return;
  70.     if (getea(buf2, reg, mode, BYTE /* actually unsized */))
  71.         return;
  72.     sprintf(sload, "PLOAD%c", value & 0x0200 ? 'R' : 'W');
  73.     if (getfc(buf1, (int)(value & 0x1f)) == -1)
  74.         return;
  75.     instprint(ops2f(2), sload, buf1, buf2);
  76.  
  77.     valid = 1;
  78. }
  79.  
  80. static void
  81. pvalid(m68kword inst, unsigned long value)
  82. {
  83.     int    reg = inst & 7;
  84.     int    mode = (inst >> 3) & 7;
  85.  
  86.     if (!ISACEA(mode, reg))
  87.         return;
  88.  
  89.     if (value == 0x2800)
  90.         strcpy(buf1, "VAL");
  91.     else if ((value & 0xfff8) == 0x2c00)
  92.         sprintf(buf1, "A%d", (int)(value & 7));
  93.     else
  94.         return;
  95.     if (getea(buf2, reg, mode, BYTE /* actually unsized */))
  96.         return;
  97.     instprint(ops2f(2), "PVALID", buf1, buf2);
  98.  
  99.     valid = 1;
  100. }
  101.  
  102. static void
  103. pflush(m68kword inst, unsigned long value)
  104. {
  105.     int    eareg = inst & 7;
  106.     int    eamode = (inst >> 3) & 7;
  107.     int    mode = (value >> 10) & 7;
  108.     int    mask = (value >> 5) & 0xf;
  109.     char    sflush[8];
  110.  
  111.     /*
  112.      * Should this be enforced when (mode & 2) == 0?
  113.      */
  114.     if (!ISACEA(eamode, eareg))
  115.         return;
  116.  
  117.     if (mode == 1) {
  118.         if (value & 0x3ff)
  119.             return;
  120.         instprint(ops2f(0), "PFLUSHA");
  121.     } else {
  122.         if ((mask & 8) && CPU(chip) >= MC68030)
  123.             return;
  124.         immsprintf(buf2, mask);
  125.         if (getfc(buf1, (int)(value & 0x1f)) == -1)
  126.             return;
  127.         strcpy(sflush, "PFLUSH");
  128.         if (mode & 1) {
  129.             if (CPU(chip) >= MC68030)
  130.                 return;
  131.             strcat(sflush, "S");
  132.         }
  133.         if (mode & 2) {
  134.             if (getea(buf3, eareg, eamode,
  135.               BYTE /* actually unsized */))
  136.                 return;
  137.             instprint(ops2f(3) | sharp2f(2), sflush, buf1, buf2,
  138.               buf3);
  139.         } else
  140.             instprint(ops2f(2) | sharp2f(2), sflush, buf1, buf2);
  141.     }
  142.  
  143.     valid = 1;
  144. }
  145.  
  146. static void
  147. pflushr(m68kword inst, unsigned long value)
  148. {
  149.     int    reg = inst & 7;
  150.     int    mode = (inst >> 3) & 7;
  151.  
  152.     if (value != 0xa000)
  153.         return;
  154.     if (!ISMEA(mode, reg))
  155.         return;
  156.  
  157.     if (getea(buf1, reg, mode, BYTE /* actually unsized */))
  158.         return;
  159.     instprint(ops2f(1), "PFLUSHR", buf1);
  160.  
  161.     valid = 1;
  162. }
  163.  
  164. static void
  165. pmove(m68kword inst, unsigned long value)
  166. {
  167.     int    reg = inst & 7;
  168.     int    mode = (inst >> 3) & 7;
  169.     int    pmmureg = (value >> 10) & 7;
  170.     int    size;
  171.     char    *cp1, *cp2;
  172.     int    fd = value & 0x0100;
  173.  
  174.     /*
  175.      * Sizes:
  176.      *
  177.      * MC68851
  178.      * -------
  179.      * Double long:    CRP, SRP, DRP
  180.      * Long:    TC
  181.      * Word:    BAC, BAD, AC, PSR, PCSR
  182.      * Byte:    CAL, VAL, SCC
  183.      *
  184.      * MC68030
  185.      * -------
  186.      * Double long:    CRP, SRP
  187.      * Long:    TC, TT0, TT1
  188.      * Word:    MMUSR
  189.      */
  190.  
  191.     strcpy(buf3, "PMOVE");
  192.     if (CPU(chip) >= MC68030) {
  193.         if (!ISACEA(mode, reg))
  194.             return;
  195.  
  196.         switch ((value >> 13) & 7) {
  197.         case 0:
  198.             if ((value & 0x18ff) != 0x0800)
  199.                 return;
  200.             sprintf(buf1, "TT%d", pmmureg & 1);
  201.             break;
  202.         case 2:
  203.             if (value & 0x10ff)
  204.                 return;
  205.             switch (pmmureg) {
  206.             case 0:
  207.                 strcpy(buf1, "TC");
  208.                 break;
  209.             case 2:
  210.                 strcpy(buf1, "SRP");
  211.                 break;
  212.             case 3:
  213.                 strcpy(buf1, "CRP");
  214.                 break;
  215.             default:
  216.                 return;
  217.             }
  218.             break;
  219.         case 3:
  220.             if (value & 0x1dff)
  221.                 return;
  222.             strcpy(buf1, "MMUSR");
  223.             break;
  224.         default:
  225.             return;
  226.         }
  227.         if (fd) {
  228.             if (value & 0x0200)
  229.                 return;
  230.             strcat(buf3, "FD");
  231.         }
  232.     } else {
  233.         /* MC68851 */
  234.         if ((value & 0x2000) == 0) {
  235.             if (pmmureg >= 1 && pmmureg <= 3
  236.               && (ISDATA(mode) || ISDIRECT(mode)))
  237.                 return;
  238.     
  239.             switch (pmmureg) {
  240.             case 0:
  241.                 strcpy(buf1, "TC");
  242.                 size = LONGWORD;
  243.                 break;
  244.             case 1:
  245.                 strcpy(buf1, "DRP");
  246.                 size = DOUBLELONGWORD;
  247.                 break;
  248.             case 2:
  249.                 strcpy(buf1, "SRP");
  250.                 size = DOUBLELONGWORD;
  251.                 break;
  252.             case 3:
  253.                 strcpy(buf1, "CRP");
  254.                 size = DOUBLELONGWORD;
  255.                 break;
  256.             case 4:
  257.                 strcpy(buf1, "CAL");
  258.                 size = BYTE;
  259.                 break;
  260.             case 5:
  261.                 strcpy(buf1, "VAL");
  262.                 size = BYTE;
  263.                 break;
  264.             case 6:
  265.                 strcpy(buf1, "SCC");
  266.                 size = BYTE;
  267.                 break;
  268.             case 7:
  269.                 strcpy(buf1, "AC");
  270.                 size = WORD;
  271.                 break;
  272.             }
  273.         } else {
  274.             int    num = (value >> 2) & 7;
  275.  
  276.             if (!ISAEA(mode, reg))
  277.                 return;
  278.     
  279.             size = WORD;
  280.             switch (pmmureg) {
  281.             case 0:
  282.                 if (num)
  283.                     return;
  284.                 strcpy(buf1, "PSR");
  285.                 break;
  286.             case 1:
  287.                 if (num || (value & 0x0200) == 0)
  288.                     return;
  289.                 strcpy(buf1, "PCSR");
  290.                 break;
  291.             case 4:
  292.                 sprintf(buf1, "BAD%d", num);
  293.                 break;
  294.             case 5:
  295.                 sprintf(buf1, "BAC%d", num);
  296.                 break;
  297.             default:
  298.                 return;
  299.             }
  300.         }
  301.     }
  302.     if (getea(buf2, reg, mode, size))
  303.         return;
  304.     if (value & 0x0200) {
  305.         cp1 = buf1;
  306.         cp2 = buf2;
  307.     } else {
  308.         cp1 = buf2;
  309.         cp2 = buf1;
  310.     }
  311.  
  312.     instprint(ops2f(2), buf3, cp1, cp2);
  313.  
  314.     valid = 1;
  315. }
  316.  
  317. static void
  318. ptest(m68kword inst, unsigned long value)
  319. {
  320.     int    reg = inst & 7;
  321.     int    mode = (inst >> 3) & 7;
  322.     int    level = (value >> 10) & 7;
  323.     int    areg = (value >> 5) & 7;
  324.     char    sareg[3];
  325.     char    stest[7];
  326.  
  327.     if (!ISACEA(mode, reg))
  328.         return;
  329.     if (getea(buf2, reg, mode, BYTE /* actually unsized */))
  330.         return;
  331.     sprintf(stest, "PTEST%c", value & 0x0200 ? 'R' : 'W');
  332.     if (getfc(buf1, (int)(value & 0x1f)) == -1)
  333.         return;
  334.     immsprintf(buf3, level);
  335.     if (value & 0x0100) {
  336.         sprintf(sareg, "A%d", areg);
  337.         instprint(ops2f(4) | sharp2f(3), stest, buf1, buf2, buf3,
  338.           sareg);
  339.     } else
  340.         instprint(ops2f(3) | sharp2f(3), stest, buf1, buf2, buf3);
  341.  
  342.     valid = 1;
  343. }
  344.  
  345. void
  346. pgen(m68kword inst)
  347. {
  348.     unsigned long    value;
  349.     int        failure;
  350.  
  351.     value = getval(WORD, &failure) & 0xffff;
  352.     if (failure)
  353.         return;
  354.  
  355.     switch ((value >> 13) & 7) {
  356.     case 0:
  357.         if (CPU(chip) >= MC68030)
  358.             pmove(inst, value);
  359.         break;
  360.     case 1:
  361.         switch ((value >> 10) & 7) {
  362.         case 0:
  363.             pload(inst, value);
  364.             break;
  365.         case 2: /* FALLTHROUGH */
  366.         case 3:
  367.             if (PMMU(chip) == MC68851)
  368.                 pvalid(inst, value);
  369.             break;
  370.         default:
  371.             pflush(inst, value);
  372.             break;
  373.         }
  374.         break;
  375.     case 2: /* FALLTHROUGH */
  376.     case 3:
  377.         pmove(inst, value);
  378.         break;
  379.     case 4:
  380.         ptest(inst, value);
  381.         break;
  382.     case 5:
  383.         if (PMMU(chip) == MC68851)
  384.             pflushr(inst, value);
  385.         break;
  386.     default:
  387.         return;
  388.     }
  389. }
  390.